using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer
{
    /// <summary>
    /// Enchants, inherits m_Items, easiest way to support enchants for now
    /// </summary>
    public class Enchant : Item
    {
        public static List<Enchant>[] Enchants;
        public static List<Enchant>[] FilteredEnchants;
        public static List<Enchant> TwoHand = new List<Enchant>();
        public static List<Enchant> Shield = new List<Enchant>();
        public static List<Enchant> Finger = new List<Enchant>();
        // Head = 0, Neck, Shoulder, Back, Chest, Wrist, Hands, Waist, Legs, Feet, Finger1, Finger2, Trinket1, Trinket2, MainHand, OffHand, Ranged
        public static Enchant None = new Enchant();
        [Flags]
        public enum EnchantSlot { None = 0, Head = 1, Shoulder = 2, Back = 4, Chest = 8, Wrist = 16, Hands = 32, Legs = 64, Feet = 128, Finger = 256, OneHand = 512, TwoHand = 1024, Shield = 2048 };
        private EnchantSlot m_Slot;

        public EnchantSlot Slot
        {
            get { return m_Slot; }
            set { m_Slot = value; }
        }
        public Enchant Copy()
        {
            List<Attribute> list = new List<Attribute>();
            list.AddRange(this.Attributes);
            Enchant retval = new Enchant(this.Name, list, m_Slot);
            return retval;
        }
        public override int Id
        {
            get
            {
                return (int)(uint)m_Name.GetHashCode();
            }
        }
        public Enchant()
        {
            m_Name = "None";
            m_Slot =  (EnchantSlot)Enum.Parse(typeof(EnchantSlot), "4095");
            m_Attributes = new List<Attribute>();
        }
        public Enchant(string name, List<Attribute> attrs, EnchantSlot slot)
        {
            m_Attributes = attrs;
            m_Name = name;
            m_Slot = slot;
        }
        // head, shoulder, back, chest, wrist, hand, leg, feet, finger1, weapon, possible other stuff      
        public static List<Enchant> parseEnchants(string[] names)
        {
            List<Enchant> retval = new List<Enchant>();
            for (int i = 0; i < names.Length; i++)
            {
                foreach (Enchant enchant in Enchants[i])
                {
                    if (enchant.Name == names[i])
                    {
                        retval.Add(enchant);
                    }
                }
            }
            return retval;
        }
        public static void InitEnchants()
        {
            List<Enchant> list = new List<Enchant>();
            // head start
            //
            List<Attribute> attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 35));
            attr.Add(new Attribute(AttributeName.MP5, 7));
            list.Add(new Enchant("Glyph of Renewal", attr, EnchantSlot.Head));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 22));
            attr.Add(new Attribute(AttributeName.HitSpellRating, 14));
            list.Add(new Enchant("Glyph of Power", attr, EnchantSlot.Head));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 34));
            attr.Add(new Attribute(AttributeName.HitRating, 16));
            list.Add(new Enchant("Glyph of Ferocity", attr, EnchantSlot.Head));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Strength, 17));
            attr.Add(new Attribute(AttributeName.Intellect, 16));
            list.Add(new Enchant("Glyph of the Outcast", attr, EnchantSlot.Head));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 10));
            attr.Add(new Attribute(AttributeName.DodgeRating, 10));
            attr.Add(new Attribute(AttributeName.BlockValue, 15));
            list.Add(new Enchant("Presence of Might", attr, EnchantSlot.Head));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.DefenseRating, 16));
            attr.Add(new Attribute(AttributeName.DodgeRating, 17));
            list.Add(new Enchant("Glyph of the Defender", attr, EnchantSlot.Head));
            // head end
            //
            // shoulder start
            //
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 33));
            attr.Add(new Attribute(AttributeName.MP5, 4));
            list.Add(new Enchant("Greater Inscription of Faith", attr, EnchantSlot.Shoulder));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 18));
            attr.Add(new Attribute(AttributeName.CritSpellRating, 10));
            list.Add(new Enchant("Greater Inscription of Discipline", attr, EnchantSlot.Shoulder));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 30));
            attr.Add(new Attribute(AttributeName.CritRating, 10));
            list.Add(new Enchant("Greater Inscription of Vengeance", attr, EnchantSlot.Shoulder));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.DefenseRating, 15));
            attr.Add(new Attribute(AttributeName.DodgeRating, 10));
            list.Add(new Enchant("Greater Inscription of Warding", attr, EnchantSlot.Shoulder));
            // shoulder end
            //
            // back start
            //
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Armor, 120));
            list.Add(new Enchant("Major Armor", attr, EnchantSlot.Back));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 12));
            list.Add(new Enchant("Major Agility", attr, EnchantSlot.Back));
            // back end
            //
            // chest start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.MP5, 6));
            list.Add(new Enchant("Restore Mana Prime", attr, EnchantSlot.Chest));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Health, 150));
            list.Add(new Enchant("Exceptional Health", attr, EnchantSlot.Chest));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Mana, 150));
            list.Add(new Enchant("Exceptional Mana", attr, EnchantSlot.Chest));
            attr = new List<Attribute>();            
            attr.Add(new Attribute(AttributeName.Intellect, 6));
            attr.Add(new Attribute(AttributeName.Stamina, 6));
            attr.Add(new Attribute(AttributeName.Strength, 6));
            attr.Add(new Attribute(AttributeName.Agility, 6));
            attr.Add(new Attribute(AttributeName.Spirit, 6));
            list.Add(new Enchant("Exceptional Stats", attr, EnchantSlot.Chest));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.ResilienceRating, 15));
            list.Add(new Enchant("Major Resilience", attr, EnchantSlot.Chest));
            // chest end
            //
            // bracer start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 15));
            list.Add(new Enchant("Spellpower", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.DefenseRating, 12));
            list.Add(new Enchant("Major Defense", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.MP5, 6));
            list.Add(new Enchant("Restore Mana Prime", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 30));
            list.Add(new Enchant("Superior Healing", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 24));
            list.Add(new Enchant("Assault", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 12));
            list.Add(new Enchant("Fortitude", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Intellect, 12));
            list.Add(new Enchant("Major Intellect", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Strength, 12));
            list.Add(new Enchant("Brawn", attr, EnchantSlot.Wrist));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Intellect, 4));
            attr.Add(new Attribute(AttributeName.Stamina, 4));
            attr.Add(new Attribute(AttributeName.Strength, 4));
            attr.Add(new Attribute(AttributeName.Agility, 4));
            attr.Add(new Attribute(AttributeName.Spirit, 4));
            list.Add(new Enchant("Exceptional Stats", attr, EnchantSlot.Wrist));
            // bracer end
            // hands
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 20));
            list.Add(new Enchant("Major Spellpower", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.HitSpellRating, 15));
            list.Add(new Enchant("Spell Strike", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 35));
            list.Add(new Enchant("Major Healing", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 26));
            list.Add(new Enchant("Assault", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.CritSpellRating, 10));
            list.Add(new Enchant("Blasting", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Strength, 15));
            list.Add(new Enchant("Major Strength", attr, EnchantSlot.Hands));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 15));
            list.Add(new Enchant("Major Agility", attr, EnchantSlot.Hands));
            // hands end
            // legs start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 35));
            attr.Add(new Attribute(AttributeName.Stamina, 20));
            list.Add(new Enchant("Runic Spellthread", attr, EnchantSlot.Legs));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 66));
            attr.Add(new Attribute(AttributeName.Stamina, 20));
            list.Add(new Enchant("Golden Spellthread", attr, EnchantSlot.Legs));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 12));
            attr.Add(new Attribute(AttributeName.Stamina, 40));
            list.Add(new Enchant("Nethercleft Leg Armor", attr, EnchantSlot.Legs));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 50));
            attr.Add(new Attribute(AttributeName.CritRating, 12));
            list.Add(new Enchant("Nethercobra Leg Armor", attr, EnchantSlot.Legs));
            // legs end
            // feet start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.HitRating, 10));
            list.Add(new Enchant("Surefooted", attr, EnchantSlot.Feet));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 6));
            list.Add(new Enchant("Cat's Swiftness", attr, EnchantSlot.Feet));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 9));
            list.Add(new Enchant("Boar's Speed", attr, EnchantSlot.Feet));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.HP5, 4));
            attr.Add(new Attribute(AttributeName.MP5, 4));
            list.Add(new Enchant("Vitality", attr, EnchantSlot.Feet));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 12));
            list.Add(new Enchant("Dexterity", attr, EnchantSlot.Feet));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 12));
            list.Add(new Enchant("Fortitude", attr, EnchantSlot.Feet));
            // feet stop
            // finger start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Special, 99999));
            list.Add(new Enchant("Weapon Might", attr, EnchantSlot.Finger));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Intellect, 4));
            attr.Add(new Attribute(AttributeName.Stamina, 4));
            attr.Add(new Attribute(AttributeName.Strength, 4));
            attr.Add(new Attribute(AttributeName.Agility, 4));
            attr.Add(new Attribute(AttributeName.Spirit, 4));
            list.Add(new Enchant("Stats", attr, EnchantSlot.Finger));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 20));
            list.Add(new Enchant("Healing Power", attr, EnchantSlot.Finger));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 20));
            list.Add(new Enchant("Spell Power", attr, EnchantSlot.Finger));
            // finger stop
            // shield start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 18));
            list.Add(new Enchant("Major Stamina", attr, EnchantSlot.Shield));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Intellect, 12));
            list.Add(new Enchant("Intellect", attr, EnchantSlot.Shield));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.BlockRating, 15));
            list.Add(new Enchant("Shield Block", attr, EnchantSlot.Shield));
            // shield end
            // weapons start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Special, 1000000));
            list.Add(new Enchant("Major Striking", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Special, 1000010));
            attr.Add(new Attribute(AttributeName.Special, 1000011));
            list.Add(new Enchant("Mongoose", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Special, 1000020));
            list.Add(new Enchant("Crusader", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Healing, 85));
            list.Add(new Enchant("Major Healing", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.SpellDamage, 40));
            list.Add(new Enchant("Major Spellpower", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.FireSpellDamage, 50));
            attr.Add(new Attribute(AttributeName.ArcaneSpellDamage, 50));
            list.Add(new Enchant("Sunfire", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.ShadowSpellDamage, 54));
            attr.Add(new Attribute(AttributeName.FrostSpellDamage, 54));
            list.Add(new Enchant("Soulfrost", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Intellect, 30));
            list.Add(new Enchant("Major Intellect", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Strength, 20));
            list.Add(new Enchant("Potency", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 15));
            list.Add(new Enchant("Agility", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Spirit, 20));
            list.Add(new Enchant("Mighty Spirit", attr, EnchantSlot.OneHand | EnchantSlot.TwoHand));
            // weapons end
            // twohand start
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Special, 1000030));
            list.Add(new Enchant("Superior Impact", attr, EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Agility, 35));
            list.Add(new Enchant("Major Agility", attr, EnchantSlot.TwoHand));
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.AttackPower, 70));
            list.Add(new Enchant("Savagery", attr, EnchantSlot.TwoHand));
            // twohand stop
            // special
            attr = new List<Attribute>();
            attr.Add(new Attribute(AttributeName.Stamina, 8));
            list.Add(new Enchant("Knothide Armor Set", attr, EnchantSlot.Chest | EnchantSlot.Hands | EnchantSlot.Legs | EnchantSlot.Feet));
            // populating array below
            TwoHand.Add(Enchant.None);
            Shield.Add(Enchant.None);
            Finger.Add(Enchant.None);
            Enchants = new List<Enchant>[Enum.GetNames(typeof(SlotName)).Length - 1];
            // { None = 0, Head = 1, Shoulder = 2, Back = 4, Chest = 8, Wrist = 16, Hands = 32, Legs = 64, Feet = 128, Finger = 256, OneHand = 512, TwoHand = 1024, Shield = 2048 };
            int[] Mapping = new int[] { 0, -1, 1, 2, 3, 4, 5, -1, 6, 7, 8, 8, -1, -1, 9, 9, -1, 10, 11 };
            for (int i = 0; i < Enchants.Length; i++)
            {
                Enchants[i] = new List<Enchant>();
                Enchants[i].Add(None);
            }
            foreach (Enchant enchant in list)
            {
                for (int i = 0; i < Enchants.Length; i++)
                {
                    EnchantSlot eslot = (EnchantSlot)(int)Math.Pow(2, i); ;
                    if ((enchant.Slot & eslot) > 0)
                    {
                        switch (eslot)
                        {
                            case EnchantSlot.Head:
                                Enchants[(int)SlotName.Head].Add(enchant);
                                break;
                            case EnchantSlot.Shoulder:
                                Enchants[(int)SlotName.Shoulder].Add(enchant);
                                break;
                            case EnchantSlot.Back:
                                Enchants[(int)SlotName.Back].Add(enchant);
                                break;
                            case EnchantSlot.Chest:
                                Enchants[(int)SlotName.Chest].Add(enchant);
                                break;
                            case EnchantSlot.Wrist:
                                Enchants[(int)SlotName.Wrist].Add(enchant);
                                break;
                            case EnchantSlot.Hands:
                                Enchants[(int)SlotName.Hands].Add(enchant);
                                break;
                            case EnchantSlot.Legs:
                                Enchants[(int)SlotName.Legs].Add(enchant);
                                break;
                            case EnchantSlot.Feet:
                                Enchants[(int)SlotName.Feet].Add(enchant);
                                break;
                            case EnchantSlot.Finger:
                                Finger.Add(enchant);
                                break;
                            case EnchantSlot.OneHand:
                                Enchants[(int)SlotName.MainHand].Add(enchant);
                                Enchants[(int)SlotName.OffHand].Add(enchant);
                                break;
                            case EnchantSlot.TwoHand:
                                TwoHand.Add(enchant);
                                break;
                            case EnchantSlot.Shield:
                                Shield.Add(enchant);
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
    }
}
